/*
 * =====================================================================================
 *
 *       Filename:  string.c
 *
 *    Description:  常见的string函数
 *
 *        Version:  1.0
 *        Created:  2014年12月3日
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  maguorong,banana family 
 *        Company:  Xidian University
 *
 * =====================================================================================
 */
#include "type.h"
#include "string.h"

/*
 *  * ba_strlen - Find the length of a string
 *   @s: The string to be sized
 */
 int ba_strlen(const char *s)
 {
      const char *sc;
        if(!s)return 0;
        for (sc = s; *sc != '\0'; sc++);
        return sc - s;
 }
 
 /*
  *   ba_tolower - 大写字母转小写字母
  *   @u: The string to be sized
  */
char ba_tolower(const char u)
  {
   if(u >='A' && u <= 'Z') return u+32;
   else return u;
  
  }



char *ba_strtolower(const char *u,char *ret)
  { char *i=ret;
    while(*u!='\0'){
	*ret++ = ba_tolower(*u++);
	}
	return i;
  }

 
 /*
  *   ba_toupper - 小写字母转大写字母
  *   @u: The string to be sized
  */  
char ba_toupper(const char u)
  {
   if(u >='a' && u <= 'z') return u-32;
   else  return u;
   
  }


char *ba_strtoupper(const char *u,char *ret)
  { char *i=ret;
    while(*u!='\0'){
	*ret++ = ba_toupper(*u++);
	}
	return i;
  } 

  
/*
 *
 * ba_strnlen - Find the length of a length-limited string
 * @s: The string to be sized
 * @num: The maximum number of bytes to search
 */
 int ba_strnlen(const char *s,int num)
  {
     const char *sc;
	  if(!s)return 0;
      for (sc = s; num-- && *sc != '\0'; ++sc);
      return sc - s;
  }
  
  /*
   * ba_strcpy - Copy a %NUL terminated string
   * @dest: Where to copy the string to
   * @src: Where to copy the string from
   */
  char *ba_strcpy(char *dest, const char *src)
  {
      char *tmp = dest;
	  if(!src||!dest)return NULL;
      while ((*dest++ = *src++) != '\0');
      return tmp;
  }
  
  /*
   * ba_strncpy - Copy a length-limited, %NUL-terminated string
   * @dest: Where to copy the string to
   * @src: Where to copy the string from
   * @count: The maximum number of bytes to copy
   *
   * The result is not %NUL-terminated if the source exceeds
   * @count bytes.
   *
   * In the case where the length of @src is less than  that  of
   * count, the remainder of @dest will be padded with %NUL.
   *
   */
  char *ba_strncpy(char *dest, const char *src, unsigned int count)
  {
      char *tmp = dest;
      if(!src||!dest)return NULL;
      while (count) {
              if ((*tmp = *src) == '\0') break;/* src到尽头后不再自加使得dest后面填'\0'了 */
              src++;
              tmp++;
              count--;
      }
      return dest;
  }
  
  /*
   * ba_strcat - Append one %NUL-terminated string to another
   * @dest: The string to be appended to
   * @src: The string to append to it
   */
  char *ba_strcat(char *dest, const char *src)
  {
      char *tmp = dest;
      if(!dest||!src) return NULL;
      while (*dest)
          dest++;
      while ((*dest++ = *src++) != '\0')
          ;
      return tmp;
  }
  
  /*
   * ba_strncat - Append a length-limited, %NUL-terminated string to another
   * @dest: The string to be appended to
   * @src: The string to append to it
   * @count: The maximum numbers of bytes to copy
   *
   * Note that in contrast to strncpy(), strncat() ensures the result is
   * terminated.
   */
  char *ba_strncat(char *dest, const char *src, int count)
  {
      char *tmp = dest;
      if(!dest||!src) return NULL;
      if (count) {
          while (*dest)
              dest++;
          while ((*dest++ = *src++) != 0) {
             if (--count == 0) {
                 *dest = '\0';
                 break;
             }
         }
     }
     return tmp;
 }
 
 /*
  * ba_strcmp - Compare two strings
  * @cs: One string
  * @ct: Another string
  */
 int ba_strcmp(const char *cs, const char *ct)
 {
     unsigned char c1, c2;
     
     while (1) {
         c1 = *cs++;
         c2 = *ct++;
         if (c1 != c2)
             return c1 < c2 ? -1 : 1;
         if (!c1)
             break;
     }
     return 0;
 }
 
 /*
  * ba_strncmp - Compare two length-limited strings
  * @cs: One string
  * @ct: Another string
  * @count: The maximum number of bytes to compare
  */
 int ba_strncmp(const char *cs, const char *ct,unsigned int count)
 {
     unsigned char c1, c2;
 
     while (count) {
         c1 = *cs++;
         c2 = *ct++;
         if (c1 != c2)
             return c1 < c2 ? -1 : 1;
         if (!c1)
             break;
         count--;
     }
     return 0;
 }
 
 /*
  * ba_strfidchr - Find the first occurrence of a character in a string
  * @s: The string to be searched
  * @c: The character to search for
  */
int ba_strfidchr(const char *s,const char c)
 {   int i = 0;
     if(!s)return NULL;
     for ( ;*s != c;s++,i++)
         if (*s == '\0')
             return NULL;
     return i;
 }
 
 /*
  * ba_strfidchrnum - Find a character in a string number
  * @s: The string to be searched
  * @c: The character to search for
  */
int ba_strfidchrnum(const char *s, const char c)
 {   int i = 0;
     for ( ;*s != '\0'; s++){
          if (*s == c) i++;
	     }
	 return i;
 }
 
 /*
  * ba_memcmp - Compare two areas of memory
  * @cs: One area of memory
  * @ct: Another area of memory
  * @count: The size of the area.
  */
 int ba_memcmp(const void *cs, const void *ct, unsigned int count)
 {
     const unsigned char *su1, *su2;
     int res = 0;
 
     for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
         if ((res = *su1 - *su2)!=0)
             break;
     return res;
 }
 
 /*
  * ba_memcpy - Copy one area of memory to another
  * @dest: Where to copy to
  * @src: Where to copy from
  * @count: The size of the area.
  *
  *
  */
 void *ba_memcpy(void *dest, const void *src, unsigned int count)
 {
     char *tmp = dest;
     const char *s = src;
     if(!dest||!src) return NULL;
     while (count--)
         *tmp++ = *s++;
     return dest;
 }
 
#if 0
 void *ba_memmove(void *dest , const void *src , unsigned int size)
 {
     char *d = dest;
     const char *s = src;
     unsigned int i;
     /* 判断地址高低, 可出现重叠区域 */
     if (d < s) {
         for (i = 0; i < size; ++i)
              *(d+i) = *(s+i);
     } else if (d > s) {
         i = size;
         while (i-- > 0)
            *(d+i) = *(s+i);
     }
 
     return dest;
 }
#endif
void *ba_memmove (void * dst,const void * src,unsigned int count)

{

         void * ret = dst;

         if (dst <= src || (char *)dst >= ((char *)src + count))

         {

                   // 若dst和src区域没有重叠，则从起始处开始逐一拷贝

                   while (count--)

                   {

                            *(char *)dst = *(char *)src;

                            dst = (char *)dst + 1;

                            src = (char *)src + 1;

                   }

         }

         else

         { // 若dst和src 区域交叉，则从尾部开始向起始位置拷贝，这样可以避免数据冲突

                   dst = (char *)dst + count - 1;

                   src = (char *)src + count - 1;

                   while (count--)

                   {

                            *(char *)dst = *(char *)src;

                            dst = (char *)dst - 1;

                            src = (char *)src - 1;

                   }

         }

         return(ret);

} 

 /*
  * ba_strstr - Find the first substring in a %NUL terminated string  
  * @s1: The string to be searched
  * @s2: The string to search for
  */
 char *ba_strstr(const char *s1, const char *s2)
 {
     unsigned int l1, l2;
 
     l2 = ba_strlen(s2);
     if (!l2)
         return (char *)s1;
     l1 = ba_strlen(s1);
     while (l1 >= l2) {
         l1--;
         if (!ba_memcmp(s1, s2, l2))
             return (char *)s1;
         s1++;
     }
     return NULL;
 }
 
 /*
  * ba_strnstr - Find the first substring in a length-limited string
  * @s1: The string to be searched
  * @s2: The string to search for
  * @len: the maximum number of characters to search
  */
 char *ba_strnstr(const char *s1, const char *s2, unsigned int len)
 {
     unsigned int l2;
     l2 = ba_strlen(s2);
    if (!l2)
         return (char *)s1;
     while (len >= l2) {
         len--;
         if (!ba_memcmp(s1, s2, l2))
             return (char *)s1;
         s1++;
     }
     return NULL;
 }
